import {
  Group,
  isSelectEntryEdited,
  isTextAreaEntryEdited,
  isTextFieldEntryEdited,
  ListGroup,
  SelectEntry,
  TextAreaEntry,
  TextFieldEntry,
  DropdownButton,
  HeaderButton, CreateIcon,
} from "@bpmn-io/properties-panel";
import {isAny} from "bpmn-js/lib/features/modeling/util/ModelingUtil";
import {useService} from "bpmn-js-properties-panel";
import {getBusinessObject, is} from "bpmn-js/lib/util/ModelUtil";
import { UserProgressDialog, AuthProgressDialog, ConditionProgressDialog, FormProgressDialog, ExpressionProgressDialog } from "@/components/PropertiesPanelExtension/provider/index";
import {getChoseUser, getChoseAuth, getChoseCondition, getFormVariable} from "@/api/camunda/camunda";
import { listFormByStart} from '@/api/camunda/form'
import {jsx, jsxs} from "@bpmn-io/properties-panel/preact/jsx-runtime";
import {find} from "min-dash";
import { getFormByCurrentNodeBefore } from '@/utils/camundaUtils'


// 常量
const collectionConstant = "${assigneeList}"
const elementVariableConstant = "assignee"
const assigneeConstant = "${assignee}"
const extensionPropertiesNameAssignee = "assignee"
const extensionPropertiesNameAuth = "auth"
const extensionPropertiesNameCondition = "condition"
const AssigneeAlias = '人员'
const AuthAlias = '权限'
const ConditionAlias = '规则'
const FormAlias = '表单'
const ExpressionAlias = '表达式'


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class MyPropertiesProviderModule {
    constructor(propertiesPanel, injector) {
        propertiesPanel.registerProvider(this);
        this._injector = injector;
    }
    getGroups(element) {
        return groups => {
            groups = groups.concat(getGroups(element, this._injector));
            return groups;
        };
    }
}
MyPropertiesProviderModule.$inject = ['propertiesPanel', 'injector'];
function getGroups(element, injector) {
    let groups = [
      GeneralGroup(element, injector),
    ]
    const source = element.businessObject.sourceRef
    if (isAny(element, ['bpmn:SequenceFlow']) && source && source.$type === 'bpmn:ExclusiveGateway'){
      groups.push(ExpressionGroup(element, injector))
    }
    if (isAny(element, ['bpmn:UserTask'])) {
      if(element.businessObject.loopCharacteristics){
        groups.push(AssigneeGroup(element, injector))
      } else {
        groups.push(UserAssigneeGroup(element, injector))
      }
      groups.push(ConditionGroup(element, injector))
      groups.push(AuthGroup(element, injector))
    }
    if(isAny(element, ['bpmn:StartEvent', 'bpmn:UserTask'])){
      groups.push(FormRefGroup(element, injector))
    }
    // contract: if a group returns null, it should not be displayed at all
    return groups.filter(group => group !== null);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function MultiInstanceGroup(element, injector) {
  const translate = injector.get('translate');
  const group = {
    label: translate('人员'),
    id: 'multiInstance',
    component: Group,
    entries: [...MultiInstanceProps$2({
      element
    })]
  };
  if (group.entries.length) {
    return group;
  }
  return null;
}

function MultiInstanceProps$2(props) {
  const {
    element
  } = props;
  if (!isMultiInstanceSupported$1(element)) {
    return [];
  }
  return [{
    id: 'completionCondition',
    component: CompletionCondition$1,
    isEdited: isTextFieldEntryEdited
  }];
}

function CompletionCondition$1(props) {
  const {
    element
  } = props;
  const bpmnFactory = useService('bpmnFactory');
  const debounce = useService('debounceInput');
  const commandStack = useService('commandStack');
  const translate = useService('translate');
  const getValue = () => {
    return getCompletionConditionValue(element);
  };
  const setValue = value => {
    return commandStack.execute('element.updateModdleProperties', updateFormalExpression(element, 'completionCondition', value, bpmnFactory));
  };
  return TextFieldEntry({
    element,
    id: 'completionCondition',
    label: translate('Completion condition'),
    getValue,
    setValue,
    debounce
  });
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function AssigneeGroup(element, injector) {
  const translate = injector.get('translate');
  const entries = [...AssigneePropertiesNameProps({
    element,
    injector,
  })];
  return {
    id: 'general',
    label: translate(AssigneeAlias),
    entries,
    component: Group
  };
}

function AuthGroup(element, injector) {
  const translate = injector.get('translate');
  const entries = [...AuthPropertiesNameProps({
    element
  })];
  return {
    id: 'general',
    label: translate(AuthAlias),
    entries,
    component: Group
  };
}

function ConditionGroup(element, injector) {
  const translate = injector.get('translate');
  const entries = [...ConditionPropertiesNameProps({
    element
  })];
  return {
    id: 'general',
    label: translate(ConditionAlias),
    entries,
    component: Group
  };
}

function FormRefGroup(element, injector) {
  const translate = injector.get('translate');
  const entries = [...FormPropertiesNameProps({
    element
  })];
  return {
    id: 'general',
    label: translate(FormAlias),
    entries,
    component: Group
  };
}

function UserAssigneeGroup(element, injector) {
  const translate = injector.get('translate');
  const entries = [...UserAssigneePropertiesNameProps({
    element,
    injector,
  })];
  return {
    id: 'general',
    label: translate(AssigneeAlias),
    entries,
    component: Group
  };
}

function ExpressionGroup(element, injector) {
  const translate = injector.get('translate');
  const entries = [...ExpressionPropertiesNameProps({
    element
  })];
  return {
    id: 'general',
    label: translate(ExpressionAlias),
    entries,
    component: Group
  };
}

function AssigneePropertiesNameProps(props) {
  const {
    element
  } = props;
  if (!isAny(element, ['bpmn:UserTask'])) {
    return [];
  }
  if(!element.businessObject.loopCharacteristics){
    return [];
  }

  return [{
    id: 'name',
    component: AssigneeName$3,
    isEdited: isTextAreaEntryEdited
  },{
    component: AssigneeButton
  }];
}

function AuthPropertiesNameProps(props) {
  const {
    element
  } = props;
  if (!isAny(element, ['bpmn:UserTask'])) {
    return [];
  }

  return [{
    id: 'name',
    component: AuthName$3,
    isEdited: isTextAreaEntryEdited
  },{
    component: AuthButton
  }];
}

function ConditionPropertiesNameProps(props) {
  const {
    element
  } = props;
  if (!isAny(element, ['bpmn:UserTask'])) {
    return [];
  }
  return [{
    id: 'name',
    component: ConditionName$3,
    isEdited: isTextAreaEntryEdited
  },{
    component: ConditionButton
  }];
}

function FormPropertiesNameProps(props) {
  const {
    element
  } = props;
  if (!isFormSupported(element)) {
    return [];
  }
  return [{
    id: 'name',
    component: FormName$3,
    isEdited: isTextAreaEntryEdited
  },{
    component: FormButton
  }];
}

function UserAssigneePropertiesNameProps(props) {
  const {
    element
  } = props;
  if (!isAny(element, ['bpmn:UserTask'])) {
    return [];
  }
  if(element.businessObject.loopCharacteristics){
    return [];
  }

  return [{
    id: 'name',
    component: UserAssigneeName$3,
    isEdited: isTextAreaEntryEdited
  },{
    component: UserAssigneeButton
  }];
}

function ExpressionPropertiesNameProps(props) {
  const {
    element
  } = props;
  if (!isFlow(element)) {
    return [];
  }
  return [{
    id: 'name',
    component: ExpressionName$3,
    isEdited: isTextAreaEntryEdited
  },{
    component: ExpressionButton
  }];
}


function AssigneeName$3(props) {
  const {element} = props;
  const property = getPropertyByName(element, extensionPropertiesNameAssignee)
  const debounce = useService('debounceInput');
  return TextAreaEntry({
    element,
    id: 'name',
    debounce,
    getValue: element => {
      return property.value
    },
    disabled: true,
    autoResize: false
  });
}

function AuthName$3(props) {
  const {element} = props;
  const property = getPropertyByName(element, extensionPropertiesNameAuth)
  const debounce = useService('debounceInput');
  return TextAreaEntry({
    element,
    id: 'name',
    debounce,
    getValue: element => {
      return property.value
    },
    disabled: true,
    autoResize: false
  });
}

function ConditionName$3(props) {
  const {element} = props;
  const property = getPropertyByName(element, extensionPropertiesNameCondition)
  const debounce = useService('debounceInput');
  return TextAreaEntry({
    element,
    id: 'name',
    debounce,
    getValue: element => {
      return property.value
    },
    disabled: true,
    autoResize: false
  });
}

function FormName$3(props) {
  const {element} = props;
  const debounce = useService('debounceInput');
  const businessObject = getBusinessObject(element);
  const getValue = () => {
    return businessObject.get('camunda:formRef');
  };
  return TextAreaEntry({
    element,
    id: 'name',
    debounce,
    getValue,
    disabled: true,
    autoResize: false
  });
}

function UserAssigneeName$3(props) {
  const {element} = props;
  const debounce = useService('debounceInput');
  const businessObject = getBusinessObject(element);
  const getValue = () => {
    return businessObject.get('camunda:assignee');
  };
  return TextAreaEntry({
    element,
    id: 'name',
    debounce,
    getValue,
    disabled: true,
    autoResize: false
  });
}

function ExpressionName$3(props) {
  const {element} = props;
  const debounce = useService('debounceInput');
  const businessObject = getBusinessObject(element);
  const getValue = () => {
    return businessObject.conditionExpression.body;
  };
  return TextAreaEntry({
    element,
    id: 'name',
    debounce,
    getValue,
    disabled: true,
    autoResize: false
  });
}

function AssigneeButton(props) {
  const {
    element
  } = props;
  const translate = useService('translate');
  const commandStack = useService('commandStack');
  const property = getPropertyByName(element, extensionPropertiesNameAssignee)
  const functionButton = () => {
    getChoseUser(property.value || '')
      .then(({data}) => {
        UserProgressDialog(
          {
            openUserDialog:true,
            title: AssigneeAlias,
            property: property,
            propertyName: extensionPropertiesNameAssignee,
            userList: data.selectUserList,
            checkUserList: data.checkSelectUserList,
            commandStack: commandStack,
            element: element,
          }
        )
      })
  }
  return jsxs(HeaderButton, {
    title: "设置分配人",
    class: "properties-button",
    onClick: functionButton,
    children: translate('设置')
  });
}

function AuthButton(props) {
  const {
    element
  } = props;
  const translate = useService('translate');
  const commandStack = useService('commandStack');
  const property = getPropertyByName(element, extensionPropertiesNameAuth)
  const functionButton = () => {
    getChoseAuth(property.value || '')
      .then(({data}) => {
        AuthProgressDialog(
          {
            openAuthDialog:true,
            title: AuthAlias,
            property: property,
            propertyName: extensionPropertiesNameAuth,
            authList: data.authChoseList,
            checkAuthList: data.checkAuthChoseList,
            commandStack: commandStack,
            element: element,
          }
        )
      })
  }
  return jsxs(HeaderButton, {
    title: "设置权限",
    class: "properties-button",
    onClick: functionButton,
    children: translate('设置')
  });
}

function ConditionButton(props) {
  const {
    element
  } = props;
  const translate = useService('translate');
  const commandStack = useService('commandStack');
  const property = getPropertyByName(element, extensionPropertiesNameCondition)
  const functionButton = () => {
    getChoseCondition()
      .then(({data}) => {
        let split = property.value.split(";");
        ConditionProgressDialog(
          {
            openConditionDialog:true,
            title: ConditionAlias,
            success: split[0] || '',
            error: split[1] || '',
            property: property,
            propertyName: extensionPropertiesNameCondition,
            conditionList: data,
            commandStack: commandStack,
            element: element,
          }
        )
      })
  }
  return jsxs(HeaderButton, {
    title: "设置规则",
    class: "properties-button",
    onClick: functionButton,
    children: translate('设置')
  });
}

function FormButton(props) {
  const {
    element
  } = props;
  const translate = useService('translate');
  const commandStack = useService('commandStack');
  const functionButton = () => {
    listFormByStart({
      page: 0,
      size: 10
    })
      .then(({data}) => {
        FormProgressDialog(
          {
            openFormDialog: true,
            title: FormAlias,
            formList: data.rows,
            total: data.total,
            commandStack: commandStack,
            element: element,
            checkForm: element.businessObject.formRef
          }
        )
      })
  }
  return jsxs(HeaderButton, {
    title: "设置表单",
    class: "properties-button",
    onClick: functionButton,
    children: translate('设置')
  });
}

function UserAssigneeButton(props) {
  const {
    element
  } = props;
  const translate = useService('translate');
  const commandStack = useService('commandStack');
  const property = getPropertyByName(element, extensionPropertiesNameAssignee)
  const functionButton = () => {
    getChoseUser('')
      .then(({data}) => {
        UserProgressDialog(
          {
            multipleChoice:true,
            openUserDialog:true,
            title: AssigneeAlias,
            property: property,
            propertyName: extensionPropertiesNameAssignee,
            userList: data.selectUserList,
            checkUserList: data.checkSelectUserList,
            commandStack: commandStack,
            element: element,
            checkUser: element.businessObject.assignee,
          }
        )
      })
  }
  return jsxs(HeaderButton, {
    title: "设置分配人",
    class: "properties-button",
    onClick: functionButton,
    children: translate('设置')
  });
}

function ExpressionButton(props) {
  const {
    element
  } = props;
  const translate = useService('translate');
  const commandStack = useService('commandStack');
  const businessObject = getBusinessObject(element);
  const property = businessObject.conditionExpression;
  const functionButton = () => {
    if(element.businessObject.sourceRef.$type === 'bpmn:ExclusiveGateway') {
      let formList = []
      getFormByCurrentNodeBefore(element.businessObject, formList)
      getFormVariable(formList)
        .then(({data}) => {
          ExpressionProgressDialog(
            {
              openExpressionDialog:true,
              title: ExpressionAlias,
              property: property,
              propertyName: extensionPropertiesNameCondition,
              expressionList: data,
              commandStack: commandStack,
              element: element,
              expression: property.body,
            }
          )
        }).catch()
    }
  }
  return jsxs(HeaderButton, {
    title: "设置表达式",
    class: "properties-button",
    onClick: functionButton,
    children: translate('设置')
  });
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


function GeneralGroup(element, injector) {
  const translate = injector.get('translate');
  const entries = [...NameProps({element}), ...VersionTagProps({element})];
  return {
    id: 'general',
    label: translate('基本信息'),
    entries,
    component: Group
  };
}

function VersionTagProps(props) {
  const {
    element
  } = props;
  if (!isAny(element, ['bpmn:Process'])) {
    return [];
  }
  return [{
    id: 'calledElementVersionTag',
    component: CalledElementVersionTag,
    isEdited: isTextFieldEntryEdited
  }]
}

function NameProps(props) {
    const {
        element
    } = props;
    if (isAny(element, ['bpmn:Collaboration', 'bpmn:DataAssociation', 'bpmn:Association'])) {
        return [];
    }
    return [{
        id: 'name',
        component: Name$3,
        isEdited: isTextAreaEntryEdited
    }];
}

function CalledElementVersionTag(props) {
  const {
    element
  } = props;
  const modeling = useService('modeling');
  const translate = useService('translate');
  const debounce = useService('debounceInput');
  const getValue = () => {
    return getBusinessObject(element).get('camunda:versionTag');
  };
  const setValue = value => {
    modeling.updateProperties(element, {
      versionTag: value
    });
  };
  return jsx(TextFieldEntry, {
    element: element,
    id: "versionTag",
    label: translate('版本标签'),
    getValue: getValue,
    setValue: setValue,
    debounce: debounce
  });
}

function Name$3(props) {
    const {
        element
    } = props;
    const modeling = useService('modeling');
    const debounce = useService('debounceInput');
    const translate = useService('translate');

    // (1) default: name
    let options = {
        element,
        id: 'name',
        label: translate('名称'),
        debounce,
        setValue: value => {
            modeling.updateProperties(element, {
                name: value
            });
        },
        getValue: element => {
            return element.businessObject.name;
        },
        autoResize: false
    };
    return TextAreaEntry(options);
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////                                     ///////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const formOptions = []
const options = []
const LOW_PRIORITY = 500;
const CAMUNDA_PLATFORM_GROUPS = [];

class CamundaPlatformPropertiesProvider {
    constructor(propertiesPanel, injector) {
        propertiesPanel.registerProvider(LOW_PRIORITY, this);
        this._injector = injector;
        getUserPostList(options)
    }
    getGroups(element) {
        return groups => {
          let id = ''
          if(element.businessObject.$type === 'bpmn:Process'){
            id = element.businessObject.id
          } else {
            id = element.businessObject.$parent.id
          }
          formOptions.push({
            value: '1',
            label: '2'
          })
            // (1) add Camunda Platform specific groups
            groups = groups.concat(this._getGroups(element));

          updateMultiInstanceGroup(groups, element);

          return groups;
        };
    }
    _getGroups(element) {
        console.log(element)
        // const groups = CAMUNDA_PLATFORM_GROUPS.map(createGroup => createGroup(element, this._injector));
        const groups = CAMUNDA_PLATFORM_GROUPS.map(createGroup => createGroup(element, this._injector));

        // contract: if a group returns null, it should not be displayed at all
        return groups.filter(group => group !== null);
    }
}
CamundaPlatformPropertiesProvider.$inject = ['propertiesPanel', 'injector'];

function FlowConditionGroup(element, injector) {
  const translate = injector.get('translate');
  const group = {
    label: translate('Condition'),
    id: 'CamundaPlatform__Condition',
    component: Group,
    entries: [...ConditionProps({
      element
    })]
  };
  if (group.entries.length) {
    return group;
  }
  return null;
}

function ConditionProps(props) {
  const {
    element
  } = props;
  if (!(is(element, 'bpmn:SequenceFlow') && isConditionalSource(element.source)) && !getConditionalEventDefinition(element)) {
    return [];
  }
  const entries = [];
  entries.push({
    id: 'conditionType',
    component: ConditionType,
    isEdited: isSelectEntryEdited
  });

  const conditionType = getConditionType(element);
  if (conditionType === 'expression') {
    entries.push({
      id: 'conditionExpression',
      component: ConditionExpression,
      isEdited: isTextFieldEntryEdited
    });
  }
  return entries;
}
function ConditionType(props) {
  const {
    element
  } = props;
  const commandStack = useService('commandStack');
  const bpmnFactory = useService('bpmnFactory');
  const translate = useService('translate');
  const getValue = () => {
    return getConditionType(element);
  };
  const setValue = value => {
    // (1) Remove formalExpression if <none> is selected
    if (value === '') {
      updateCondition(element, commandStack, undefined);
    } else {
      // (2) Create and set formalExpression element containing the conditionExpression
      const attributes = {
        body: '',
        language: value === 'script' ? '' : undefined
      };
      const formalExpressionElement = createFormalExpression(element, attributes, bpmnFactory);
      updateCondition(element, commandStack, formalExpressionElement);
    }
  };
  const getOptions = () => [{
    value: '',
    label: translate('<none>')
  }, {
    value: 'script',
    label: translate('Script')
  }, {
    value: 'expression',
    label: translate('Expression')
  }];
  return jsx(SelectEntry, {
    element: element,
    id: "conditionType",
    label: translate('Type'),
    getValue: getValue,
    setValue: setValue,
    getOptions: getOptions
  });
}
function ConditionExpression(props) {
  const {
    element
  } = props;
  const commandStack = useService('commandStack'),
    bpmnFactory = useService('bpmnFactory'),
    translate = useService('translate'),
    debounce = useService('debounceInput');
  const getValue = () => {
    return getConditionExpression(element).get('body');
  };
  const setValue = value => {
    const conditionExpression = createFormalExpression(element, {
      body: value
    }, bpmnFactory);
    updateCondition(element, commandStack, conditionExpression);
  };
  return jsx(TextFieldEntry, {
    element: element,
    id: "conditionExpression",
    label: translate('Condition Expression'),
    getValue: getValue,
    setValue: setValue,
    debounce: debounce
  });
}


function createFormalExpression(parent, attributes, bpmnFactory) {
  return createElement('bpmn:FormalExpression', attributes, is(parent, 'bpmn:SequenceFlow') ? getBusinessObject(parent) : getConditionalEventDefinition(parent), bpmnFactory);
}
function updateCondition(element, commandStack, condition = undefined) {
  if (is(element, 'bpmn:SequenceFlow')) {
    commandStack.execute('element.updateProperties', {
      element,
      properties: {
        conditionExpression: condition
      }
    });
  } else {
    commandStack.execute('element.updateModdleProperties', {
      element,
      moddleElement: getConditionalEventDefinition(element),
      properties: {
        condition
      }
    });
  }
}
function getConditionExpression(element) {
  const businessObject = getBusinessObject(element);
  if (is(businessObject, 'bpmn:SequenceFlow')) {
    return businessObject.get('conditionExpression');
  } else if (getConditionalEventDefinition(businessObject)) {
    return getConditionalEventDefinition(businessObject).get('condition');
  }
}

// helper
const CONDITIONAL_SOURCES = ['bpmn:Activity', 'bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:ComplexGateway'];
function isConditionalSource(element) {
  return isAny(element, CONDITIONAL_SOURCES);
}
function getConditionalEventDefinition(element) {
  if (!is(element, 'bpmn:Event')) {
    return false;
  }
  return getEventDefinition$1(element, 'bpmn:ConditionalEventDefinition');
}
function getConditionType(element) {
  const conditionExpression = getConditionExpression(element);
  if (!conditionExpression) {
    return '';
  } else {
    return conditionExpression.get('language') === undefined ? 'expression' : 'script';
  }
}

function getEventDefinition$1(element, eventType) {
  const businessObject = getBusinessObject(element);
  const eventDefinitions = businessObject.get('eventDefinitions') || [];
  return find(eventDefinitions, function (definition) {
    return is(definition, eventType);
  });
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function updateMultiInstanceGroup(groups, element) {
  const multiInstanceGroup = findGroup(groups, 'multiInstance');
  if (!multiInstanceGroup) {
    return;
  }
  const {
    entries
  } = multiInstanceGroup;
  MultiInstanceProps({
    element,
    entries
  });
}
function findGroup(groups, id) {
  return groups.find(g => g.id === id);
}

function MultiInstanceProps(props) {
  const {
    element
  } = props;
  const loopCharacteristics = getLoopCharacteristics(element);
  let entries = props.entries || [];
  if (!isMultiInstanceSupported(element)) {
    return entries;
  }
  entries.push({
    id: 'collection',
    component: Collection,
    isEdited: isTextFieldEntryEdited
  }, {
    id: 'elementVariable',
    component: ElementVariable,
    isEdited: isTextFieldEntryEdited
  });
  return entries;
}

function Collection(props) {
  const {
    element
  } = props;
  const debounce = useService('debounceInput');
  const commandStack = useService('commandStack');
  const translate = useService('translate');
  const loopCharacteristics = getLoopCharacteristics(element);
  const getValue = () => {
    return getCollection(element);
  };
  const setValue = value => {
    return commandStack.execute('element.updateModdleProperties', {
      element,
      moddleElement: loopCharacteristics,
      properties: {
        'camunda:collection': value
      }
    });
  };
  return TextFieldEntry({
    element,
    id: 'collection',
    label: translate('Collection'),
    getValue,
    setValue,
    debounce
  });
}
function ElementVariable(props) {
  const {
    element
  } = props;
  const debounce = useService('debounceInput');
  const commandStack = useService('commandStack');
  const translate = useService('translate');
  const loopCharacteristics = getLoopCharacteristics(element);
  const getValue = () => {
    return getElementVariable(element);
  };
  const setValue = value => {
    return commandStack.execute('element.updateModdleProperties', {
      element,
      moddleElement: loopCharacteristics,
      properties: {
        'camunda:elementVariable': value
      }
    });
  };
  return TextFieldEntry({
    element,
    id: 'elementVariable',
    label: translate('Element variable'),
    getValue,
    setValue,
    debounce
  });
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function FormGroup(element, injector) {
    const translate = injector.get('translate');
    const group = {
        label: translate('表单'),
        id: 'CamundaPlatform__Form',
        component: Group,
        entries: [...FormProps({
            element
        })]
    };
    if (group.entries.length) {
        return group;
    }
    return null;
}
function FormProps(props) {
    const {
        element
    } = props;
    if (!isFormSupported(element)) {
        return [];
    }
    const entries = [];
    entries.push({
        id: 'formRef',
        component: FormRefOption,
        isEdited: isSelectEntryEdited
    }, {
      component: FormButton
    });
    return entries;
}

function isFormSupported(element) {
    return is(element, 'bpmn:StartEvent') && !is(element.parent, 'bpmn:SubProcess') || is(element, 'bpmn:UserTask');
}

function isFlow(element) {
  return is(element, 'bpmn:SequenceFlow')
    && element.businessObject.sourceRef
    && element.businessObject.sourceRef.$type === 'bpmn:ExclusiveGateway'
}

function FormRefOption(props) {
    const {
        element
    } = props;
    const modeling = useService('modeling');
    const translate = useService('translate');
    const businessObject = getBusinessObject(element);
    const getValue = () => {
        return businessObject.get('camunda:formRef');
    };
    const setValue = value => {
      modeling.updateProperties(element, {
        'camunda:formRef': value
      });
      modeling.updateProperties(element, {
          'camunda:formRefBinding': 'deployment'
      });
    };

    // Note: default is "latest",
    // cf. https://docs.camunda.org/manual/develop/reference/bpmn20/custom-extensions/extension-attributes/#formrefbinding

    const getOptions = () => {
      return formOptions
    };
    return SelectEntry({
        element,
        id: 'formRef',
        label: translate('请选择表单'),
        getValue,
        setValue,
        getOptions
    });
}

function getUserPostList(options) {
  options.push({
    value: '1',
    label: '1'
  })
  // listUserPost()
  //   .then(({data}) => {
  //     options.splice(0, options.length);
  //
  //     data.forEach((item) => {
  //       options.push({
  //         value: item.userId,
  //         label: item.userName + " (" + item.postName + ")"
  //       })
  //     })
  //   })
}


export default {
    __init__: ['bpmnPropertiesProvider', 'camundaPlatformPropertiesProvider'],
    bpmnPropertiesProvider: ['type', MyPropertiesProviderModule],
    camundaPlatformPropertiesProvider: ['type', CamundaPlatformPropertiesProvider]
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function UserAssignmentGroup(element, injector) {
  const translate = injector.get('translate');
  const group = {
    label: translate('指定分配人'),
    id: 'CamundaPlatform__UserAssignment',
    component: Group,
    entries: [...UserAssignmentProps({
      element
    })]
  };
  if (group.entries.length) {
    return group;
  }
  return null;
}

function UserAssignmentProps(props) {
  const {
    element
  } = props;
  if (!is(element, 'camunda:Assignable')) {
    return [];
  }
  if(element.businessObject.loopCharacteristics){
    return []
  }

  return [{
    id: 'assignee',
    component: Assignee,
    isEdited: isTextFieldEntryEdited
  }];
}

function Assignee(props) {
  const {
    element
  } = props;
  const translate = useService('translate');
  const businessObject = getBusinessObject(element);
  const commandStack = useService('commandStack');
  const getValue = () => {
    return businessObject.get('camunda:assignee');
  };
  const setValue = value => {
    commandStack.execute('element.updateModdleProperties', {
      element,
      moddleElement: businessObject,
      properties: {
        'camunda:assignee': value
      }
    });
  };

  // Note: default is "latest",
  // cf. https://docs.camunda.org/manual/develop/reference/bpmn20/custom-extensions/extension-attributes/#formrefbinding

  const getOptions = () => {
    return options
  };
  return SelectEntry({
    element,
    id: 'assignee',
    label: translate('Assignee'),
    getValue,
    setValue,
    getOptions
  });
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function getRelevantBusinessObject(element) {
  let businessObject = getBusinessObject(element);
  if (is(element, 'bpmn:Participant')) {
    return businessObject.get('processRef');
  }
  return businessObject;
}
function getPropertyName(namespace = 'camunda') {
  if (namespace === 'zeebe') {
    return 'properties';
  }
  return 'values';
}
function getProperties(element, namespace = 'camunda') {
  const businessObject = getRelevantBusinessObject(element);
  return getExtensionElementsList(businessObject, `${namespace}:Properties`)[0];
}
function getPropertiesList(element, namespace = 'camunda') {
  const businessObject = getRelevantBusinessObject(element);
  const properties = getProperties(businessObject, namespace);
  return properties && properties.get(getPropertyName(namespace));
}
function getPropertiesValueByName(element, name) {
  let businessObject = getRelevantBusinessObject(element);
  // do not offer for empty pools
  if (!businessObject) {
    return;
  }
  const properties = getPropertiesList(businessObject, 'camunda') || [];
  let value = ''
  properties.forEach((property) => {
    if(property.name === name){
      value =  property.value;
    }
  })
  return value
}
function getPropertyByName(element, name){
  let businessObject = getRelevantBusinessObject(element);
  // do not offer for empty pools
  if (!businessObject) {
    return;
  }
  const properties = getPropertiesList(businessObject, 'camunda') || [];
  let value = ''
  properties.forEach((property) => {
    if(property.name === name){
      value =  property;
    }
  })
  return value
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * Get extension elements of business object. Optionally filter by type.
 *
 * @param  {ModdleElement} businessObject
 * @param  {String} [type=undefined]
 * @returns {Array<ModdleElement>}
 */
function getExtensionElementsList(businessObject, type = undefined) {
  const extensionElements = businessObject.get('extensionElements');
  if (!extensionElements) {
    return [];
  }
  const values = extensionElements.get('values');
  if (!values || !values.length) {
    return [];
  }
  if (type) {
    return values.filter(value => is(value, type));
  }
  return values;
}


/**
 * isMultiInstanceSupported - check whether given element supports MultiInstanceLoopCharacteristics.
 *
 * @param {djs.model.Base} element
 * @return {boolean}
 */
function isMultiInstanceSupported$1(element) {
  const loopCharacteristics = getLoopCharacteristics$2(element);
  return !!loopCharacteristics && is(loopCharacteristics, 'bpmn:MultiInstanceLoopCharacteristics');
}

/**
 * getLoopCharacteristics - get loopCharacteristics of a given element.
 *
 * @param {djs.model.Base} element
 * @return {ModdleElement<bpmn:MultiInstanceLoopCharacteristics> | undefined}
 */
function getLoopCharacteristics$2(element) {
  const bo = getBusinessObject(element);
  return bo.loopCharacteristics;
}

/**
 * getCompletionConditionValue - get the completion condition value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {string} the completion condition value
 */
function getCompletionConditionValue(element) {
  const completionCondition = getCompletionCondition$1(element);
  return getBody(completionCondition);
}

/**
 * getBody - get the body of a given expression.
 *
 * @param {ModdleElement<bpmn:FormalExpression>} expression
 * @return {string} the body (value) of the expression
 */
function getBody(expression) {
  return expression && expression.get('body');
}

/**
 * getCompletionCondition - get the completion condition of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {ModdleElement<bpmn:FormalExpression>} an expression representing the completion condition
 */
function getCompletionCondition$1(element) {
  return getProperty$2(element, 'completionCondition');
}

/**
 * getProperty - get a property value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 * @param {string} propertyName
 *
 * @return {any} the property value
 */
function getProperty$2(element, propertyName) {
  const loopCharacteristics = getLoopCharacteristics$2(element);
  return loopCharacteristics && loopCharacteristics.get(propertyName);
}

/**
 * updateFormalExpression - updates a specific formal expression of the loop characteristics.
 *
 * @param {djs.model.Base} element
 * @param {string} propertyName
 * @param {string} newValue
 * @param {BpmnFactory} bpmnFactory
 */
function updateFormalExpression(element, propertyName, newValue, bpmnFactory) {
  const loopCharacteristics = getLoopCharacteristics$2(element);
  const expressionProps = {};
  if (!newValue) {
    // remove formal expression
    expressionProps[propertyName] = undefined;
    return {
      element,
      moddleElement: loopCharacteristics,
      properties: expressionProps
    };
  }
  const existingExpression = loopCharacteristics.get(propertyName);
  if (!existingExpression) {
    // add formal expression
    expressionProps[propertyName] = createFormalExpression$1(loopCharacteristics, newValue, bpmnFactory);
    return {
      element,
      moddleElement: loopCharacteristics,
      properties: expressionProps
    };
  }

  // edit existing formal expression
  return {
    element,
    moddleElement: existingExpression,
    properties: {
      body: newValue
    }
  };
}

/**
 * createFormalExpression - creates a 'bpmn:FormalExpression' element.
 *
 * @param {ModdleElement} parent
 * @param {string} body
 * @param {BpmnFactory} bpmnFactory
 *
 * @result {ModdleElement<bpmn:FormalExpression>} a formal expression
 */
function createFormalExpression$1(parent, body, bpmnFactory) {
  return createElement('bpmn:FormalExpression', {
    body: body
  }, parent, bpmnFactory);
}

/**
 * Create a new element and set its parent.
 *
 * @param {String} elementType of the new element
 * @param {Object} properties of the new element in key-value pairs
 * @param {moddle.object} parent of the new element
 * @param {BpmnFactory} factory which creates the new element
 *
 * @returns {djs.model.Base} element which is created
 */
function createElement(elementType, properties, parent, factory) {
  const element = factory.create(elementType, properties);
  if (parent) {
    element.$parent = parent;
  }
  return element;
}

/**
 * isMultiInstanceSupported - check whether given element supports camunda specific props
 * for multiInstance (ref. <camunda:Cllectable>).
 *
 * @param {djs.model.Base} element
 * @return {boolean}
 */
function isMultiInstanceSupported(element) {
  const loopCharacteristics = getLoopCharacteristics(element);
  return !!loopCharacteristics && is(loopCharacteristics, 'camunda:Collectable');
}


/**
 * getLoopCharacteristics - get loopCharacteristics of a given element.
 *
 * @param {djs.model.Base} element
 * @return {ModdleElement<bpmn:MultiInstanceLoopCharacteristics> | undefined}
 */
function getLoopCharacteristics(element) {
  const bo = getBusinessObject(element);
  return bo.loopCharacteristics;
}

// collection

/**
 * getCollection - get the 'camunda:collection' attribute value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {string} the 'camunda:collection' value
 */
function getCollection(element) {
  return getProperty(element, 'camunda:collection');
}

/**
 * getElementVariable - get the 'camunda:elementVariable' attribute value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 *
 * @return {string} the 'camunda:elementVariable' value
 */
function getElementVariable(element) {
  return getProperty(element, 'camunda:elementVariable');
}

/**
 * getProperty - get a property value of the loop characteristics.
 *
 * @param {djs.model.Base} element
 * @param {string} propertyName
 *
 * @return {any} the property value
 */
function getProperty(element, propertyName) {
  var loopCharacteristics = getLoopCharacteristics(element);
  return loopCharacteristics && loopCharacteristics.get(propertyName);
}
